#pragma once

#include "oper.h"
#include "tree.h"

// 对外提供：gen_oper_data结构体
typedef struct {
	u8_s oper_no;
} gen_oper_data_t;

static inline void gen_oper_set_oper(tree34_t* tree_p, oper_e oper0,
				     oper_e oper1, oper_e oper2) {
	tree_set_oper(tree_p, 0, oper0);
	tree_set_oper(tree_p, 1, oper1);
	tree_set_oper(tree_p, 2, oper2);
}

// 对外提供：gen_oper_init()
static inline void gen_oper_init(gen_oper_data_t* data_p, tree34_t* tree_p) {
	data_p->oper_no = 0;
	gen_oper_set_oper(tree_p, (oper_e)0, (oper_e)0, (oper_e)0);
}

// 对外提供：gen_oper_has_next()
static inline b32_s gen_oper_has_next(const gen_oper_data_t* data_p) {
	u32_s maxn_no = OPER_MAX * OPER_MAX * OPER_MAX;
	return data_p->oper_no < maxn_no - 1;
}

// 对外提供：gen_oper_next()
static inline void gen_oper_next(gen_oper_data_t* data_p, tree34_t* tree_p) {
	u32_s prev_oper_no = data_p->oper_no;
	u32_s new_oper_no = prev_oper_no + 1;
	data_p->oper_no = new_oper_no;
	union {
		struct {
			oper_e oper_0 : 2;
			oper_e oper_1 : 2;
			oper_e oper_2 : 2;
		} s;
		u32_s u;
	} su = {
		.u = new_oper_no,
	};
	gen_oper_set_oper(tree_p, su.s.oper_0, su.s.oper_1, su.s.oper_2);
}
